package com.kfzx.www.facerecognitionandlocationattendence;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.AMapLocationQualityReport;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * @author: create by lrh
 * date:        2018/7/13
 * time:        上午9:26
 * email:       598116345@qq.com
 * description: 简单的高德定位demo 设置了一些简单的参数就可以定位了
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    //声明AMapLocationClient类对象
    private AMapLocationClient mAMapLocationClient = null;
    //requestPermissions 请求权限的状态码
    private static final int CHECK_LOCATION_PERMISSION = 1;
    //高德定位的功能参数对象
    private AMapLocationClientOption mAMapLocationClientOption = null;

    //简单的控件
    private TextView mResultTextView;
    private Button mStartButton, mStopButton;
    private Button mFenceButton;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化权限
        initPermissions();

        //初始化控件
        initViews();

        //初始化定位的参数
        initLocationOptions();


    }

    /**
     * 初始化控件
     */
    private void initViews() {
        mResultTextView = (TextView) findViewById(R.id.text_view);

        mStartButton = (Button) findViewById(R.id.start_location);
        mStartButton.setOnClickListener(this);

        mStopButton = (Button) findViewById(R.id.stop_location);
        mStopButton.setOnClickListener(this);

        mFenceButton =(Button) findViewById(R.id.fence);
        mFenceButton.setOnClickListener(this);


    }

    /**
     * 点击事件的响应
     *
     * @param view
     */

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.start_location:
                startLocation();
                break;
            case R.id.stop_location:
                stopLocation();
                break;
            case R.id.fence:
                startActivity(new Intent(MainActivity.this,KeyWordFenceActivity.class));
                break;
            default:
                break;
        }

    }

    /**
     * 初始化权限，请求用户获取对应的权限 没有获取的都可直接加到列表中
     */
    private void initPermissions() {
        List<String> permissionList = new ArrayList<>();

        //用于进行网络定位
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.ACCESS_COARSE_LOCATION);
        }

        //用于访问GPS定位
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }

        //用户储存的权限，定位的一些缓存数据可能需要存储
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }

        //读取手机状态等信息，比如所网络的状态等
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.READ_PHONE_STATE);
        }

        //判断是否还有没有获得的权限，如果有，就逐个申请对应的权限
        if (permissionList.size() > 0) {
            String[] permissions = new String[permissionList.size()];
            permissionList.toArray(permissions);
            ActivityCompat.requestPermissions(MainActivity.this, permissions, CHECK_LOCATION_PERMISSION);
        }
    }

    /***
     * 初始化定位的参数的设置
     */

    private void initLocationOptions() {
        mAMapLocationClientOption = new AMapLocationClientOption();

        /*
         *locationMode是定位类型AMapLocationMode的对象，提供三个枚举常量分别代表三种定位模式。
         *Hight_Accuracy：高精度定位模式；
         *Device_Sensors：仅设备定位模式；
         *Battery_Saving：低功耗定位模式；
         *默认高精度模式 Hight_Accuracy
         */
        mAMapLocationClientOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);

        /*
         *isLocationCacheEnable是布尔型参数，true表示使用定位缓存策略；false表示不使用。
         *启用缓存策略，SDK将在设备位置未改变时返回之前相同位置的缓存结果
         *默认启用缓存策略
         */
        mAMapLocationClientOption.setLocationCacheEnable(true);

        /*
         *interval是长整型参数，用于设定连续定位间隔，毫秒级参数。
         *例如向方法传1000，连续定位启动后会以1s为间隔时间返回定位结果。
         *默认值为2000
         */
        mAMapLocationClientOption.setInterval(1 * 1000);
        /**
         * isOnceLocation是布尔型参数，true表示启动单次定位，false表示使用默认的连续定位策略。
         * 传入true，启动定位，AmapLocationClient将会返回一次定位结果。
         * 默认关闭  false
         */
//        mAMapLocationClientOption.setOnceLocation(false);

        /**
         * isOnceLocationLatest是布尔型参数，true表示获取最近3s内精度最高的一次定位结果；false表示使用默认的连续定位策略。
         * 出入true，启动定位，AmapLocationClient将会最近3s内精度最高的一次定位结果。
         * 默认值 false
         */
//        mAMapLocationClientOption.setOnceLocationLatest(false);

        /**
         * isNeedAddress是布尔型参数，true表示定位返回经纬度同时返回地址描述（定位类型是网络定位的会返回）；false表示不返回地址描述。
         * 传入true，启动定位，AmapLocationClient返回经纬度的同时会返回地址描述。注意：模式为仅设备模式(Device_Sensors)时无效。
         * 默认值 true
         */
        mAMapLocationClientOption.setNeedAddress(true);

        /**
         * isMockEnable是布尔型参数，true表示允许外界在定位SDK通过GPS定位时模拟位置，false表示不允许模拟GPS位置。
         * 传入true，启动定位，可以通过外界第三方软件对GPS位置进行模拟。注意：模式为低功耗模式(Battery_Saving)时无效。
         * 默认值 false
         */
//        mAMapLocationClientOption.setMockEnable(false);

        /**
         * isWifiActiveScan是布尔型参数，true表示会主动刷新设备wifi模块，获取到最新鲜的wifi列表（wifi新鲜程度决定定位精度）；false表示不主动刷新。
         * 传入true，启动定位，AmapLocationClient会驱动设备扫描周边wifi，获取最新的wifi列表（相比设备被动刷新会多消耗一些电量），从而获取更精准的定位结果。注意：模式为仅设备模式(Device_Sensors)时无效
         * 默认值 false
         */
        mAMapLocationClientOption.setWifiScan(true);

        /**
         * httpTimeOut是长整型参数，用于设定通过网络定位获取结果的超时时间，毫秒级。
         * 传入20000，代表网络定位超时时间为20秒。
         * 默认值 30*1000
         */
//        mAMapLocationClientOption.setHttpTimeOut(30 * 1000);

        /**
         * DEFAULT
         * 默认，国外返回英文，国内返回中文
         * EN
         * 英语，无论在国内还是国外都返回中文
         * ZH
         * 汉语，无论在国内还是国外都返回英文
         */
        mAMapLocationClientOption.setGeoLanguage(AMapLocationClientOption.GeoLanguage.DEFAULT);

        /**
         * 可选，设置是否使用传感器。默认是false
         */
//        mAMapLocationClientOption.setSensorEnable(false);
        /**
         * 设置首次定位是否等待GPS定位结果
         * 默认值：false
         * 只有在单次定位高精度定位模式下有效
         * 设置为true时，会等待GPS定位结果返回，最多等待30秒，若30秒后仍无GPS结果返回，返回网络定位结果
         */

//        mAMapLocationClientOption.setGpsFirst(false);

        /**
         * 设置退出时是否杀死进程
         * 默认值:false, 不杀死
         * 注意：如果设置为true，并且配置的service不是remote的则会杀死当前页面进程，请慎重使用
         */
//        mAMapLocationClientOption.setKillProcess(false);


        /**
         * 设置定位场景，根据场景快速修改option，不支持动态改变，修改后需要调用AMapLocationClient.startLocation()使其生效
         * 当不需要场景时，可以设置为NULL， 注意： 不建议设置场景和自定义option混合使用 设置场景后，如果已经开始定位了，
         * 建议调用一次AMapLocationClient.stopLocation(),然后主动调用一次AMapLocationClient.startLocation()以保证option正确生效
         * 当主动设置的option和场景中的option有冲突时，以后设置的为准， 比如：签到场景中默认的为单次定位，当主动设置option为连续定位时，
         * 如果先设置的场景，后改变的option，这时如果不调用startLocation不会变为连续定位，如果调用了startLocation则会变为连续定位，
         * 如果先改变option，后设置场景为签到场景，则会变为单次定位
         */

//        mAMapLocationClientOption.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn);

//        mAMapLocationClientOption.setOffset()
//        mAMapLocationClientOption.setDeviceModeDistanceFilter()


    }


    /**
     * 获取权限的状态等 ，检查一下有没有没有通过的权限
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case CHECK_LOCATION_PERMISSION:
                if (grantResults.length > 0) {
                    for (int i : grantResults) {
                        if (i != PackageManager.PERMISSION_GRANTED) {
                            Toast.makeText(MainActivity.this, "请允许相关的权限才能使用定位功能哦", Toast.LENGTH_LONG).show();
                            finish();
                        }
                    }
                }
        }
    }

    /***
     * 开始定位 将设置好的定位参数option 赋值给client，然后就可以启动startLocation（）开启定位咯
     */
    private void startLocation() {
        mAMapLocationClient = new AMapLocationClient(getApplicationContext());
//        参数设置
        mAMapLocationClient.setLocationOption(mAMapLocationClientOption);
        //设置监听定位的对象，实时返回定位数据
        mAMapLocationClient.setLocationListener(mAMapLocationListener);
        //开始定位
        mAMapLocationClient.startLocation();
    }

    /***
     * 当前活动被stop掉，也顺便stop掉定位的client 节省资源和电量等
     */

    @Override
    protected void onStop() {
        super.onStop();
        //停止定位
        stopLocation();
    }


    /***
     *  停止定位
     */
    private void stopLocation() {
        // 停止定位
        mAMapLocationClient.stopLocation();
    }

    /***
     * 随着当前活动的销毁而销毁这个定位客户端
     */
    @Override
    protected void onDestroy() {
        super.onDestroy();
        destroyLocation();

    }

    /***
     *销毁定位
     */
    private void destroyLocation() {
        if (mAMapLocationClient != null) {

            /**
             * 如果AMapLocationClient是在当前Activity实例化的，
             * 在Activity的onDestroy中一定要执行AMapLocationClient的onDestroy
             */
            mAMapLocationClient.onDestroy();
            mAMapLocationClient = null;
            mAMapLocationClientOption = null;
        }

    }


    //声明定位回调监听器
    private AMapLocationListener mAMapLocationListener = new AMapLocationListener() {
        @Override
        public void onLocationChanged(AMapLocation aMapLocation) {
            if (null != aMapLocation) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                StringBuffer sb = new StringBuffer();
                //errCode等于0代表定位成功，其他的为定位失败，具体的可以参照官网定位错误码说明
                if (aMapLocation.getErrorCode() == 0) {
                    sb.append("定位成功" + "\n");
                    /*
                    int 定位来源 获取定位结果来源
                     */
                    sb.append("定位类型: " + aMapLocation.getLocationType() + "\n");

                    /**
                     * double 经度 获取经度
                     */
                    sb.append("经    度    : " + aMapLocation.getLongitude() + "\n");
                    /**
                     * double 纬度 获取纬度
                     */
                    sb.append("纬    度    : " + aMapLocation.getLatitude() + "\n");

                    /**
                     * float 精度 获取定位精度 单位:米
                     */
                    sb.append("精    度    : " + aMapLocation.getAccuracy() + "米" + "\n");
                    /**
                     double 海拔 获取海拔高度信息
                     */
                    sb.append("海    拔    ：" + aMapLocation.getAltitude() + "米" + "\n");

                    /*
                    String  信息提供方，lbs:高德网络定位 gps:设备gps模块
                     */
                    sb.append("提供者    : " + aMapLocation.getProvider() + "\n");

                    /**
                     String 室内定位建筑物Id 获取室内定位建筑物Id
                     */
                    sb.append("室内定位建筑id ：" + aMapLocation.getBuildingId() + "\n");

                    /**
                     String 室内定位楼层 获取室内定位楼层
                     */
                    sb.append("室内定位的楼层" + aMapLocation.getFloor() + "楼" + "\n");

                    /*
                      float 速度 单位：米/秒
                     */
                    sb.append("速    度    : " + aMapLocation.getSpeed() + "米/秒" + "\n");
                    /**
                     float 方向角 获取方向角信息
                     */
                    sb.append("角    度    : " + aMapLocation.getBearing() + "\n");
                    // 获取当前提供定位服务的卫星个数
                    sb.append("星    数    : " + aMapLocation.getSatellites() + "\n");

                    /***
                     * String 国家 获取国家名称 模式为仅设备模式(Device_Sensors)时无此信息
                     */
                    sb.append("国    家    : " + aMapLocation.getCountry() + "\n");

                    /*
                    String 省 获取省名称 模式为仅设备模式(Device_Sensors)时无此信息
                     */
                    sb.append("省            : " + aMapLocation.getProvince() + "\n");

                    /*
                     String 城市 获取城市名称 模式为仅设备模式(Device_Sensors)时无此信息
                     */
                    sb.append("市            : " + aMapLocation.getCity() + "\n");
                    /*
                    String 城区 获取城区名称 模式为仅设备模式(Device_Sensors)时无此信息
                     */
                    sb.append("区            : " + aMapLocation.getDistrict() + "\n");

                    /*
                        String 街道 获取街道名称 模式为仅设备模式(Device_Sensors)时无此信息
                     */
                    sb.append("街道        ：   " + aMapLocation.getStreet() + "\n");

                    /*
                        String 街道门牌号 获取街道门牌号信息
                     */
                    sb.append("街道门牌号码 ：" + aMapLocation.getStreetNum() + "号" + "\n");

                    /*
                    String 城市编码 获取城市编码信息 模式为仅设备模式(Device_Sensors)时无此信息
                     */

                    sb.append("城市编码 : " + aMapLocation.getCityCode() + "\n");

                    /*
                    String 区域编码 获取区域编码信息 模式为仅设备模式(Device_Sensors)时无此信息
                     */

                    sb.append("区域 码   : " + aMapLocation.getAdCode() + "\n");

                    /*
                     String 地址描述 获取地址描述 模式为仅设备模式(Device_Sensors)时无此信息
                     */
                    sb.append("地    址    : " + aMapLocation.getAddress() + "\n");

                    /*
                    String 当前位置POI名称 获取当前位置的POI名称
                     */
                    sb.append("兴趣点    : " + aMapLocation.getPoiName() + "\n");

                    /*
                    String 当前位置所处AOI名称 获取当前位置所处AOI名称 模式为仅设备模式(Device_Sensors)时无此信息
                     */
                    sb.append("当前位置所处的AOI:   " + aMapLocation.getAoiName() + "\n");


                    /*
                    int 设备当前 GPS 状态 获取GPS当前状态，返回值可参考AMapLocation类提供的常量 模式为仅设备模式(Device_Sensors)时提供此信息
                     */
                    sb.append("当前GPS的状态 ： " + aMapLocation.getGpsAccuracyStatus() + "\n");


                    //定位完成的时间
                    sb.append("定位时间: " + simpleDateFormat.format(aMapLocation.getTime()) + "\n");
                } else {
                    //定位失败
                    sb.append("定位失败" + "\n");
                    sb.append("错误码:" + aMapLocation.getErrorCode() + "\n");
                    /*
                    String 定位错误信息描述 定位出现异常的描述
                     */
                    sb.append("错误信息:" + aMapLocation.getErrorInfo() + "\n");

                    /*
                    String 定位信息描述 定位信息描述  用于问题排查
                     */
                    sb.append("错误描述:" + aMapLocation.getLocationDetail() + "\n");
                }

                /*
                定位的一些详细报告
                 */
                sb.append("***定位质量报告***").append("\n");
                sb.append("* WIFI开关：").append(aMapLocation.getLocationQualityReport().isWifiAble() ? "开启" : "关闭").append("\n");
                sb.append("* GPS状态：").append(getGPSStatusString(aMapLocation.getLocationQualityReport().getGPSStatus())).append("\n");
                sb.append("* GPS星数：").append(aMapLocation.getLocationQualityReport().getGPSSatellites()).append("\n");
                sb.append("* 网络类型：" + aMapLocation.getLocationQualityReport().getNetworkType()).append("\n");
                sb.append("* 网络耗时：" + aMapLocation.getLocationQualityReport().getNetUseTime()).append("\n");
                sb.append("****************").append("\n");
                //定位之后的回调时间
                sb.append("回调时间: " + simpleDateFormat.format(System.currentTimeMillis()) + "\n");

                //解析定位结果，
                String result = sb.toString();
                mResultTextView.setText(result);
            } else {
                mResultTextView.setText("定位失败，loc is null");
            }
        }
    };

    /**
     * 获取GPS状态的字符串
     *
     * @param statusCode GPS状态码
     * @return
     */
    private String getGPSStatusString(int statusCode) {
        String str = "";
        switch (statusCode) {
            case AMapLocationQualityReport.GPS_STATUS_OK:
                str = "GPS状态正常";
                break;
            case AMapLocationQualityReport.GPS_STATUS_NOGPSPROVIDER:
                str = "手机中没有GPS Provider，无法进行GPS定位";
                break;
            case AMapLocationQualityReport.GPS_STATUS_OFF:
                str = "GPS关闭，建议开启GPS，提高定位质量";
                break;
            case AMapLocationQualityReport.GPS_STATUS_MODE_SAVING:
                str = "选择的定位模式中不包含GPS定位，建议选择包含GPS定位的模式，提高定位质量";
                break;
            case AMapLocationQualityReport.GPS_STATUS_NOGPSPERMISSION:
                str = "没有GPS定位权限，建议开启gps定位权限";
                break;
        }
        return str;
    }


}
